import static org.junit.Assert.*;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Vector;

import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.junit.Test;


/**
 * @author 		Hoang Quang Minh A0099943J
 */
public class SchedulerLogicTest {
	private static final String TEST_DATA = "testData.xls";
	private static final String TEST_LOG  = "testLog.xls";
	private static final String TEST_INPUT = "testInput.txt";
	private static final String TEST_RESULT = "testResult.txt";
	private static final String EXPECTED_FEEDBACK = "expectedFeedback.txt";
	private static final String EXPECTED_LIST = "expectedList.txt";
	
	private SchedulerLogic testLogic;
	private File input, expectedFeedback, expectedList, testResult;
	private BufferedReader reader,feedbackReader,listReader;
	private BufferedWriter writer;
	
	/**
	 * @description Create file from folder directory
	 * @return current file if file already exists, or new file otherwise
	 * @author 		Hoang Quang Minh A0099943J
	 */
	private static File createFile(String fileName) {
		File file = new File(fileName); 
		if(!file.exists()) { 
			  try {  
			    file.createNewFile(); 
			  } 
			  catch(IOException ioe) { 
			    ioe.printStackTrace(); 
			  } 
		}
		return file;
	}
	
	/**
	 * @description Populate input file with test case
	 * @author 		Hoang Quang Minh A0099943J
	 */
	private void initializeTestData() {
		input = createFile(TEST_INPUT);
		try {
			writer = new BufferedWriter(new FileWriter(input));
			writer.write("clear"); writer.newLine();
			writer.write("add meeting with John"); writer.newLine();
			writer.write("add complete homework by Friday"); writer.newLine();
			writer.write("add complete project by Fri"); writer.newLine();
			writer.write("add google code jam from mon to tue"); writer.newLine();
			writer.write("add apply for internship by next month"); writer.newLine();
			writer.write("add went to SJI from 1/1/2007 to 31/12/2009"); writer.newLine();
			writer.write("add went to Bali from 15/07/2013 to 14/07/2013"); writer.newLine();
			writer.write("add buy \"Stay\" by Rihanna by Friday"); writer.newLine();
			writer.write("add buy \"Stay\" by Rihanna /by Friday"); writer.newLine();
			writer.write("edit 1 meeting with Mary"); writer.newLine();
			writer.write("edit 2 complete homework by next Friday"); writer.newLine();
			writer.write("edit 3 complete project from 26/03/2014 to 27/03/2014"); writer.newLine();
			writer.write("THIS IS AN INVALID COMMAND"); writer.newLine();
			writer.write("del 1 2 3"); writer.newLine();
			writer.write("undo"); writer.newLine();
			writer.write("undo"); writer.newLine();
			writer.write("add prepare for final exam from next monday to next friday"); writer.newLine();
			writer.write("mark 1"); writer.newLine();
			writer.write("mark 2"); writer.newLine();
			writer.write("unmark 1"); writer.newLine();
			writer.write("unmark 1 2"); writer.newLine();
			writer.write("add"); writer.newLine();
			writer.write("edit"); writer.newLine();
			writer.write("del"); writer.newLine();
			writer.write("mark"); writer.newLine();
			writer.write("unmark"); writer.newLine();
			writer.write("add by friday"); writer.newLine();
			writer.write("edit 1 2 by friday"); writer.newLine();
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
	}
	
	/**
	 * @description	Automated Testing for Scheduler Logic
	 * @author 		Hoang Quang Minh A0099943J
	 */
	@Test
	public void testExecuteCommand() {
		initializeTestData();
		
		testLogic 			= new SchedulerLogic(TEST_DATA,TEST_LOG);
		expectedFeedback 	= createFile(EXPECTED_FEEDBACK);
		expectedList		= createFile(EXPECTED_LIST);
		testResult		 	= createFile(TEST_RESULT);
		
		String cmdString = "";
		try {
			reader 			= new BufferedReader(new FileReader(input));
			feedbackReader 	= new BufferedReader(new FileReader(expectedFeedback));
			listReader 		= new BufferedReader(new FileReader(expectedList));
			writer 			= new BufferedWriter(new FileWriter(testResult));
			while ((cmdString = reader.readLine()) != null) {
				Command testCommand = new Command(cmdString);
				String 	actual 	 = testLogic.executeCommand(testCommand),
						expected = feedbackReader.readLine();
				//writer.write(actual);
				//writer.newLine();
				assertEquals(actual,expected);
			}
			Vector <Task> outputList = testLogic.getTaskList();
			DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss");
			for (int i = 0; i < outputList.size(); i++) {
				Task currentTask = outputList.get(i);
				String startDT 		= currentTask.getStartDateTime().toString(formatter),
					   endDT   		= currentTask.getEndDateTime().toString(formatter),
					   description 	= currentTask.getDescription();
				String actual 		= (i+1) + "." + description + " " + startDT + " " + endDT,
					   expected		= listReader.readLine();
				//writer.write(actual);
				//writer.newLine();
				assertEquals(actual,expected);
			}
			writer.close();
		} catch (FileNotFoundException fnfe){
			fnfe.printStackTrace();
		} catch (IOException ioe) {
			ioe.printStackTrace();
		} catch (NullPointerException npe) {
			System.out.println(cmdString); 
		}
	}
}
